package com.zhu.day.learn;

import lombok.AllArgsConstructor;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;

public class LRUCache {
    LinkedList<Node> cache;
    int capacity;

    public LRUCache(int capacity, LinkedList<Node> cache) {
        this.cache = cache;
        this.capacity = capacity;
    }

    // -1 表示没找到
    public int get(int key) {
        Iterator<Node> iterator = cache.descendingIterator();
        int result = -1;
        while (iterator.hasNext()) {
            Node node = iterator.next();
            if (node.key == key) {
                result = node.val;
                iterator.remove();
                put(key, result); //添加到链表尾部
                break;
            }
        }
        return result;
    }

    public void put(int key, int value) {
        //先遍历查找是否有key 的元素, 有则删除，重新添加到链尾
        Iterator<Node> iterator = cache.iterator();
        while (iterator.hasNext()) {
            Node node = iterator.next();
            if (node.key == key) {
                iterator.remove();
                break;
            }
        }
        if (capacity == cache.size()) {
            //缓存已满，删除一个 最近最少访问的元素（链表头）
            cache.removeFirst();
        }
        cache.add(new Node(key, value));
    }

    public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {

//        LRUCache lruCache = new LRUCache(3,new LinkedList<>());
//        for (int i = 0; i < 10; i++) {
//            lruCache.put(i, i);
//        }
//        LinkedList<Node> caches = lruCache.cache;
//        for (Node cach : caches) {
//            System.out.print(cach.key);
//            System.out.print("  ");
//        }
        HashMap m = new HashMap(8, 0.75f);
        //获取HashMap整个类
        Class<?> mapType = m.getClass();
        //获取指定属性，也可以调用getDeclaredFields()方法获取属性数组
        Field threshold = mapType.getDeclaredField("threshold");
        //将目标属性设置为可以访问
        threshold.setAccessible(true);
        //获取指定方法，因为HashMap没有容量这个属性，但是capacity方法会返回容量值
        Method capacity = mapType.getDeclaredMethod("capacity");
        //设置目标方法为可访问
        capacity.setAccessible(true);
        //打印刚初始化的HashMap的容量、阈值和元素数量
        System.out.println("初始容量：" + capacity.invoke(m) + " 阈值：" + threshold.get(m) + " 元素数量：" + m.size());
        for (int i = 0; i < 50; i++) {
            m.put(i, i);
            //动态监测HashMap的容量、阈值和元素数量
            System.out.println("容量：" + capacity.invoke(m) + " 阈值：" + threshold.get(m) + " 元素数量：" + m.size());
        }

    }

    @AllArgsConstructor
    class Node {
        int key;
        int val;
    }
}
